﻿using System;
using log4net.Config;
using System.IO;
using System.Reflection;
using log4net;
using log4net.Repository.Hierarchy;
using log4net.Core;
using log4net.Appender;
using log4net.Layout;


namespace MWTools.Client.Common
{
    public class Logger
    {
        private static PatternLayout _layout = new PatternLayout();
        private static string LOG_PATTERN = "%d [%t] %-5p %m%n";


        public static string DefaultPattern
        {
            get { return LOG_PATTERN; }
        }


        public static void AddAppender(IAppender appender)
        {
            Hierarchy hierarchy =
                    (Hierarchy)LogManager.GetRepository();

            hierarchy.Root.AddAppender(appender);
        }


        public static void ConfigureFromResource()
        {
            Assembly commonAssembly = Assembly.GetExecutingAssembly();

            bool isProduction = commonAssembly.Location.Contains("C:\\MWTools\\MWToolsSolution\\Web\\");

            if(isProduction)
                return;

            string[] manifestResourceNames = commonAssembly.GetManifestResourceNames();

            using (Stream manifestResourceStream = commonAssembly.GetManifestResourceStream("MWTools.Client.Common.Resources.log4net.xml"))
            {
                XmlConfigurator.Configure(manifestResourceStream);
            }

            Hierarchy hierarchy = (Hierarchy)LogManager.GetRepository();
            TraceAppender tracer = new TraceAppender();
            PatternLayout patternLayout = new PatternLayout();

            patternLayout.ConversionPattern = LOG_PATTERN;
            patternLayout.ActivateOptions();

            tracer.Layout = patternLayout;
            tracer.ActivateOptions();
            hierarchy.Root.AddAppender(tracer);

            RollingFileAppender roller = new RollingFileAppender();
            roller.Threshold = Level.Error;
            roller.Layout = patternLayout;
            roller.AppendToFile = true;
            roller.RollingStyle = RollingFileAppender.RollingMode.Size;
            roller.MaxSizeRollBackups = 4;
            roller.MaximumFileSize = "100KB";
            roller.StaticLogFileName = true;
            roller.File = "errorLog.txt";
            roller.ActivateOptions();
            hierarchy.Root.AddAppender(roller);

            hierarchy.Root.Level = Level.All;
            hierarchy.Configured = true;

        }

        static Logger()
        {
            try
            {
                ConfigureFromResource();

                _layout.ConversionPattern = DefaultPattern;
                _layout.ActivateOptions();
            }
            catch (Exception ex)
            {
                
            }


        }

        #region .: Enabled Checks :.

        public static bool IsDebugEnabled(object o)
        {
            return IsDebugEnabled(o.GetType());
        }

        public static bool IsDebugEnabled(Type t)
        {
            return IsDebugEnabled(t.FullName);
        }

        public static bool IsDebugEnabled(string name)
        {
            return LogManager.GetLogger(name).IsDebugEnabled;
        }

        public static bool IsInfoEnabled(object o)
        {
            return IsInfoEnabled(o.GetType());
        }

        public static bool IsInfoEnabled(Type t)
        {
            return IsInfoEnabled(t.FullName);
        }

        public static bool IsInfoEnabled(string name)
        {
            return LogManager.GetLogger(name).IsInfoEnabled;
        }

        public static bool IsWarnEnabled(object o)
        {
            return IsWarnEnabled(o.GetType());
        }

        public static bool IsWarnEnabled(Type t)
        {
            return IsWarnEnabled(t.FullName);
        }

        public static bool IsWarnEnabled(string name)
        {
            return LogManager.GetLogger(name).IsWarnEnabled;
        }

        public static bool IsErrorEnabled(object o)
        {
            return IsErrorEnabled(o.GetType());
        }

        public static bool IsErrorEnabled(Type t)
        {
            return IsErrorEnabled(t.FullName);
        }

        public static bool IsErrorEnabled(string name)
        {
            return LogManager.GetLogger(name).IsErrorEnabled;
        }

        public static bool IsFatalEnabled(object o)
        {
            return IsFatalEnabled(o.GetType());
        }

        public static bool IsFatalEnabled(Type t)
        {
            return IsFatalEnabled(t.FullName);
        }

        public static bool IsFatalEnabled(string name)
        {
            return LogManager.GetLogger(name).IsFatalEnabled;
        }

        #endregion

        #region .: Debug :.

        public static void Debug(object o, object message)
        {
            Debug(o.GetType(), message);
        }

        public static void Debug(Type t, object message)
        {
            Debug(t.FullName, message);
        }

        public static void Debug(string name, object message)
        {
            LogManager.GetLogger(name).Debug(message);
        }

        public static void DebugFormat(object o, string format, params object[] parameters)
        {
            DebugFormat(o.GetType(), format, parameters);
        }

        public static void DebugFormat(Type t, string format, params object[] parameters)
        {
            DebugFormat(t.FullName, format, parameters);
        }

        public static void DebugFormat(string name, string format, params object[] parameters)
        {
            LogManager.GetLogger(name).DebugFormat(format, parameters);
        }

        #endregion

        #region .: Info :.

        public static void Info(object o, object message)
        {
            Info(o.GetType(), message);
        }

        public static void Info(Type t, object message)
        {
            Info(t.FullName, message);
        }

        public static void Info(string name, object message)
        {
            LogManager.GetLogger(name).Info(message);
        }

        public static void InfoFormat(object o, string format, params object[] parameters)
        {
            InfoFormat(o.GetType(), format, parameters);
        }

        public static void InfoFormat(Type t, string format, params object[] parameters)
        {
            InfoFormat(t.FullName, format, parameters);
        }

        public static void InfoFormat(string name, string format, params object[] parameters)
        {
            LogManager.GetLogger(name).InfoFormat(format, parameters);
        }

        public static void InfoFormat(string format, params object[] args)
        {
            LogManager.GetLogger(MethodInfo.GetCurrentMethod().DeclaringType).DebugFormat(format, args);
        }

        #endregion

        #region .: Warn :.

        public static void Warn(object o, object message)
        {
            Warn(o.GetType(), message);
        }

        public static void Warn(Type t, object message)
        {
            Warn(t.FullName, message);
        }

        public static void Warn(string name, object message)
        {
            LogManager.GetLogger(name).Warn(message);
        }

        public static void WarnFormat(object o, string format, params object[] parameters)
        {
            WarnFormat(o.GetType(), format, parameters);
        }

        public static void WarnFormat(Type t, string format, params object[] parameters)
        {
            WarnFormat(t.FullName, format, parameters);
        }

        public static void WarnFormat(string name, string format, params object[] parameters)
        {
            LogManager.GetLogger(name).WarnFormat(format, parameters);
        }

        #endregion

        #region .: Error :.

        public static void Error(object o, object message)
        {
            Error(o.GetType(), message);
        }

        public static void Error(Type t, object message)
        {
            Error(t.FullName, message);
        }

        public static void Error(string name, object message)
        {
            LogManager.GetLogger(name).Error(message);
        }

        public static void ErrorFormat(object o, string format, params object[] parameters)
        {
            ErrorFormat(o.GetType(), format, parameters);
        }

        public static void ErrorFormat(Type t, string format, params object[] parameters)
        {
            ErrorFormat(t.FullName, format, parameters);
        }

        public static void ErrorFormat(string name, string format, params object[] parameters)
        {
            LogManager.GetLogger(name).ErrorFormat(format, parameters);
        }

        #endregion

        #region .: Fatal :.

        public static void Fatal(object o, object message)
        {
            Fatal(o.GetType(), message);
        }

        public static void Fatal(Type t, object message)
        {
            Fatal(t.FullName, message);
        }

        public static void Fatal(string name, object message)
        {
            LogManager.GetLogger(name).Fatal(message);
        }

        public static void FatalFormat(object o, string format, params object[] parameters)
        {
            FatalFormat(o.GetType(), format, parameters);
        }

        public static void FatalFormat(Type t, string format, params object[] parameters)
        {
            FatalFormat(t.FullName, format, parameters);
        }

        public static void FatalFormat(string name, string format, params object[] parameters)
        {
            LogManager.GetLogger(name).FatalFormat(format, parameters);
        }

        #endregion
    }
}